#!/usr/bin/perl

use lib::abs qw( .. );
use strict;
use warnings;

use English qw( -no_match_vars );
use Test::More tests => 15;

BEGIN { use_ok 'Try::LiteAndTiny', qw( try catch ) };

sub _eval {
    local $EVAL_ERROR;
    local $Test::Builder::Level = $Test::Builder::Level + 2;
    return ( scalar(eval { $ARG[0]->(); 1 }), $EVAL_ERROR );
}


sub lives_ok (&$) {
    my ( $code, $desc ) = @ARG;
    local $Test::Builder::Level = $Test::Builder::Level + 1;

    my ( $ok, $error ) = _eval($code);

    ok($ok, $desc );

    diag "error: $EVAL_ERROR" unless $ok;
}

sub throws_ok (&$$) {
    my ( $code, $regex, $desc ) = @ARG;
    local $Test::Builder::Level = $Test::Builder::Level + 1;

    my ( $ok, $error ) = _eval($code);

    if ( $ok ) {
        fail($desc);
    } else {
        like($error || '', $regex, $desc );
    }
}


lives_ok {
    try {
        die "foo";
    };
} "basic try";

throws_ok {
    try {
        die "foo";
    } catch { die $ARG };
} qr/foo/, "rethrow";


{
    local $EVAL_ERROR = "magic";
    is( try { 42 }, 42, "try block evaluated" );
    is( $EVAL_ERROR, "magic", '$EVAL_ERROR untouched' );
}

{
    local $EVAL_ERROR = "magic";
    is( try { die "foo" }, undef, "try block died" );
    is( $EVAL_ERROR, "magic", '$EVAL_ERROR untouched' );
}

{
    local $EVAL_ERROR = "magic";
    like( (try { die "foo" } catch { $ARG }), qr/foo/, "catch block evaluated" );
    is( $EVAL_ERROR, "magic", '$EVAL_ERROR untouched' );
}

is( scalar(try { "foo", "bar", "gorch" }), "gorch", "scalar context" );
is_deeply( [ try {qw(foo bar gorch)} ], [qw(foo bar gorch)], "list context" );



sub Evil::DESTROY {
    eval { "oh noes" };
}

sub Evil::new { bless { }, $ARG[0] }

{
    local $EVAL_ERROR = "magic";
    local $ARG = "other magic";

    try {
        my $object = Evil->new;
        die "foo";
    } catch {
        pass("catch invoked");
        local $TODO = "i don't think we can ever make this work sanely, maybe with SIG{__DIE__}";
        like($ARG, qr/foo/);
    };

    is( $EVAL_ERROR, "magic", '$@ untouched' );
    is( $ARG, "other magic", '$ARG untouched' );
}
